package com.atguigu.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.atguigu.client.OrderFeignClient;
import com.atguigu.config.AlipayConfig;
import com.atguigu.constant.MqConst;
import com.atguigu.entity.OrderInfo;
import com.atguigu.entity.PaymentInfo;
import com.atguigu.enums.PaymentStatus;
import com.atguigu.enums.PaymentType;
import com.atguigu.mapper.PaymentInfoMapper;
import com.atguigu.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 支付信息表 服务实现类
 * </p>
 *
 * @author GuoJH
 * @since 2021-09-10
 */
@Service
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    //生成支付宝付款的二维码
    @Override
    public String createQrCode(Long orderId) throws Exception {
        //1.根据id获取订单的信息
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        //2.保存支付的信息
        savePaymentInfo(orderInfo);
        //3.调用支付宝二维码的接口 生成二维码
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //设置调用成功的同步通知 跳转的页面
        request.setReturnUrl(AlipayConfig.return_payment_url);
        //设置调用成功后的异步通知 支付宝给返回的一些数据
        request.setNotifyUrl(AlipayConfig.notify_payment_url);
        //将参数封装为一个map中
        Map<String, Object> map = new HashMap<>();
        map.put("out_trade_no",orderInfo.getOutTradeNo());//商户订单号
        map.put("total_amount",orderInfo.getTotalMoney());//总金额
        map.put("subject","天气转凉,注意保暖!");//订单的标题
        map.put("product_code","FAST_INSTANT_TRADE_PAY");//产品码  目前只支持FAST_INSTANT_TRADE_PAY
        //将map转为json格式
        String mapString = JSON.toJSONString(map);
        request.setBizContent(mapString);//最后返回的是json的数据格式
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
        if(response.isSuccess()){
            return response.getBody();//如果调用接口成功 则返回响应的主体内容
        } else {
            System.out.println("调用失败");
        }
        return "";
    }
    //从paramMap中获取订单的交易编号(商户订单号) 通过编号获取订单的信息
    @Override
    public PaymentInfo getPaymentInfoByOutTradeNo(String outTradeNo) {
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("out_trade_no",outTradeNo);
        PaymentInfo paymentInfo = baseMapper.selectOne(wrapper);
        return paymentInfo;
    }
    //更新支付信息的状态
    @Override
    public void updatePaymentInfo(PaymentInfo paymentInfo, Map<String, String> paramMap) {
        //从paramMap获取支付宝交易单号trade_no
        String tradeNo = paramMap.get("trade_no");
        paymentInfo.setTradeNo(tradeNo);
        paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(paramMap.toString());
        baseMapper.updateById(paymentInfo);

        //同时利用rabbitmq发送消息给order修改订单的状态
        rabbitTemplate.convertAndSend(MqConst.PAY_ORDER_EXCHANGE,MqConst.PAY_ORDER_ROUTE_KEY,paymentInfo.getOrderId());
    }
    //支付宝的退款接口
    @Override
    public boolean refund(Long orderId) throws Exception {
        //通过id获取订单的信息
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderInfo.getOutTradeNo());//商户订单号
        bizContent.put("refund_amount",orderInfo.getTotalMoney());//退款金额
        bizContent.put("refund_reason","棉袄不暖和");//退款的原因
//        bizContent.put("trade_no", "HZ01RF001");//支付宝交易号  这里传入商户订单号 或者 支付宝交易号都可
        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            //如果退款成功  则关闭支付订单的 交易状态
            PaymentInfo paymentInfo = new PaymentInfo();
            paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
            QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("out_trade_no",orderInfo.getOutTradeNo());
            baseMapper.update(paymentInfo,wrapper);
            //更新完成后 就不需要在进行退款了
            return true;
        } else {
            return false;
        }
    }
    //关闭支付宝的交易接口
    @Override
    public boolean closeAlipayTrade(Long orderId) throws Exception {
        //通过订单id获取订单信息
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no",orderInfo.getOutTradeNo());
        request.setBizContent(bizContent.toString());
        AlipayTradeCloseResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            return true;
        } else {
            return false;
        }
    }
    //查询支付宝的内部订单信息
    @Override
    public boolean queryAlipayTrade(Long orderId) throws Exception {
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no",orderInfo.getOutTradeNo());
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            return true;
        } else {
            return false;
        }
    }
    //关闭支付订单的状态
    @Override
    public void closePaymentInfo(Long orderId) {
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderId);
        Integer count = baseMapper.selectCount(wrapper);
        if (count==0){
            return;
        }
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
        baseMapper.update(paymentInfo,wrapper);
    }

    //保存支付的信息
    private void savePaymentInfo(OrderInfo orderInfo) {
        //先判断是否有支付信息 有的话直接返回
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderInfo.getId());
        wrapper.eq("payment_type",PaymentType.ALIPAY.name());
        Integer count = baseMapper.selectCount(wrapper);
        if (count>0){
            return;
        }
        //没有则再保存支付信息
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId()+"");
        paymentInfo.setPaymentType(PaymentType.ALIPAY.name());
        paymentInfo.setPaymentMoney(orderInfo.getTotalMoney());
        paymentInfo.setPaymentContent(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        paymentInfo.setCreateTime(new Date());
        baseMapper.insert(paymentInfo);
    }
}
